﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Viettel.VOFFICE.DAO.Models;

namespace Viettel.VOFFICE.DAO.DAL.Repository
{
    /// <summary>
    /// các node có thể có trong một luồng
    /// nhiều node này gộp lại với chung 1 flowid và có  relation với nhau tạo thành luồng
    /// </summary>
    public class NodeRepository : IRepository<Node>
    {
        private VOFFICEContext context;
        public NodeRepository(VOFFICEContext context)
        {
            if (context == null)
            {
                throw new Exception("Context must be init");
            }
            this.context = context;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Node> Get()
        {
            return context.Nodes.OrderByDescending(o => o.UpdatedAt).Select(o => o);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Node GetById(object id)
        {
            return context.Nodes.Find(int.Parse(id.ToString()));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public IEnumerable<Node> FindByName(object s)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="T"></param>
        public void Insert(Node T)
        {
            if (null != T)
            {
                context.Nodes.Add(T);
                Save();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        public void Delete(object id)
        {
            var T = GetById(id);
            if (null != T)
            {
                Delete(T);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="T"></param>
        public void Delete(Node T)
        {
            if (null != T)
            {
                context.Nodes.Attach(T);
                context.Nodes.Remove(T);
                Save();
            }
        }

        /// <summary>
        /// Cập nhập node
        /// </summary>
        /// <param name="T"></param>
        public void Update(Node T)
        {
            context.Entry(T).State = EntityState.Modified;
            Save();
        }

        /// <summary>
        /// 
        /// </summary>
        public void Save()
        {
            context.SaveChanges();
        }

        /// <summary>
        /// lấy toàn bộ node của luồng
        /// </summary>
        /// <param name="flowId"></param>
        /// <returns></returns>
        public IEnumerable<Node> GetByFlow(int flowId)
        {
            return context.Nodes.Where(o => o.FlowId == flowId).OrderByDescending(o => o.IsStart).ThenBy(o => o.CreatedAt).Select(o => o);
        }

        /// <summary>
        /// Cập nhập toàn start của node về 1 giá trị true hoặc false
        /// </summary>
        /// <param name="flowId"></param>
        /// <param name="differenceNodeId"></param>
        /// <param name="IsStart"></param>
        public void UpdateStarting(int flowId, int differenceNodeId, bool IsStart = false)
        {
            context.Nodes.Where(o => o.FlowId == flowId && o.Id != differenceNodeId).ToList().ForEach(t =>
                {
                    t.IsStart = IsStart;
                    context.Entry(t).State = EntityState.Modified;
                });
            Save();
        }

        /// <summary>
        /// Lấy nút bắt đầu bằng id của luồng
        /// </summary>
        /// <param name="flowId"></param>
        /// <returns></returns>
        public Node GetStartByFlow(int flowId)
        {
            return context.Nodes.FirstOrDefault(o => o.FlowId == flowId && o.IsStart == true);
        }
    }
}
